package concurrency;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


public class Transfer {

    public static void main(String[] args) throws InterruptedException {
        int[] accounts = new int[20];
        Arrays.fill(accounts, 10000);
        Object[] locks = new Object[]{new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object()
                , new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object(), new Object()};
        Random r = new Random();

        // 用来阻塞主线程，确保次数执行够
        CountDownLatch cdl = new CountDownLatch(10 * 100);

        // 验证数据是否正确
        AtomicInteger amount19 =  new AtomicInteger(0);

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 100; j++) {
                    int accIndex1 = r.nextInt(20);
                    synchronized (locks[accIndex1]) {
                        int amount = r.nextInt(100) + 1;
                        if (accounts[accIndex1] > amount) {
                            if (accIndex1 == 19) {
//                                System.out.println(String.format("acc:%s minus %d = %s", accIndex1, amount, accounts[accIndex1] - amount));
                                amount19.addAndGet(amount);
                            }
                            accounts[accIndex1] = accounts[accIndex1] - amount;
                        }
                    }
                    int accIndex2 = r.nextInt(20);
                    synchronized (locks[accIndex2]) {
                        int amount = r.nextInt(100) + 1;
                        if (accounts[accIndex2] >= amount) {
                            accounts[accIndex2] = accounts[accIndex2] - amount;
                            if (accIndex2 == 19) {
//                                System.out.println(String.format("acc:%s minus %d = %s", accIndex2, amount, accounts[accIndex2] - amount));
                                amount19.addAndGet(amount);
                            }

                        }
                    }
                    cdl.countDown();
                }
            }).start();
        }
        cdl.await();
        System.out.println("amount19:" + amount19.get());
        System.out.println(Arrays.toString(accounts));
    }
}
